/*
 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
 * Robert Lougher <rob@jamvm.org.uk>.
 *
 * This file is part of JamVM.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2,
 * or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

/* Ensure operand stack is double-word aligned.  This leads to
   better double floating-point performance 确保操作数堆栈双字对齐。这将带来更好的双浮点性能 */
#define ALIGN_OSTACK(pntr) (uintptr_t*)(((uintptr_t)(pntr) + 7) & ~7)

#define CREATE_TOP_FRAME(ee, class, mb, sp, ret)                \
{                                                               \
    /* last就是栈顶 */            \
    Frame *last = ee->last_frame;                               \
    /* TOTO dummy（假的、模型） 这个地方啥意思 难道dummy代表的就是上一个方法栈的结束位置？*/   \
    Frame *dummy = (Frame *)(last->ostack+last->mb->max_stack); \
    /* 新栈帧 */ \
    Frame *new_frame;                                           \
    /* 新操作栈 */ \
    uintptr_t *new_ostack;                                      \
                                                                \
    /* 然后这里设置sp为上一个方法栈结束的 + 1 是啥意思啊？*/ \
    ret = (void*) (sp = (uintptr_t*)(dummy+1));                 \
    /* 反着推 sp肯定是上一个方法的栈顶了 只有这样，加上当前方法的 最大变量数（为啥是这个，不是max_stack?) 看不懂了..*/                         \
    new_frame = (Frame *)(sp + mb->max_locals);                 \
    /* 这里 new_frame + 1 不就到了下一个栈帧的位置了吗？*/\
    new_ostack = ALIGN_OSTACK(new_frame + 1);                   \
                                                                \
    if((char*)(new_ostack + mb->max_stack) > ee->stack_end) {   \
        if(ee->overflow++) {                                    \
            /* Overflow when we're already throwing stack       \
               overflow.  Stack extension should be enough      \
               to throw exception, so something's seriously     \
               gone wrong - abort the VM! 当我们已经抛出堆栈溢出时。\
               堆栈扩展应该足以抛出异常，所以有些事情发生了严重的错误——  \
               中止VM!*/                                        \
            printf("Fatal stack overflow!  Aborting VM.\n");    \
            exitVM(1);                                          \
        }                                                       \
        ee->stack_end += STACK_RED_ZONE_SIZE;                   \
        signalException(java_lang_StackOverflowError, NULL);    \
        return NULL;                                            \
    }                                                           \
                                                                \
    dummy->mb = NULL;                                           \
    dummy->ostack = sp;                                         \
    dummy->prev = last;                                         \
                                                                \
    new_frame->mb = mb;                                         \
    new_frame->lvars = sp;                                      \
    new_frame->ostack = new_ostack;                             \
                                                                \
    new_frame->prev = dummy;                                    \
    ee->last_frame = new_frame;                                 \
}

#define POP_TOP_FRAME(ee)                                       \
    ee->last_frame = ee->last_frame->prev->prev;
